package cn.dlc.com.account.service.impl;

import cn.dlc.com.account.dao.AccountDao;
import cn.dlc.com.account.entity.Account;
import cn.dlc.com.account.service.AccountService;
import cn.dlc.com.log.dao.LocalConfirmLogDao;
import cn.dlc.com.log.entity.LocalConfirmLog;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.dromara.hmily.core.concurrent.threadlocal.HmilyTransactionContextLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @author 邓立川
 * @date 2021/1/19 11:36
 * @desc 添加当前类的描述信息
 */
@Service
@Slf4j
@Transactional
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LocalConfirmLogDao confirmLogDao;

    @Override
    @Hmily(confirmMethod = "confirm",cancelMethod = "cancel")
    public void transfer(String accountNo, Double amount) {

        // 获取全局事务id
        String transId = HmilyTransactionContextLocal.getInstance().get().getTransId();

        // 这个方法是空的
        log.info("try 方法是空的....: {}",transId);

    }

    // 执行失败的话必须要抛出一个异常
    public void confirm(String accountNo, Double amount){
        // 获取全局事务id
        String transId = HmilyTransactionContextLocal.getInstance().get().getTransId();
        System.out.println("transId: " + transId);

        // 【confirm幂等校验】判断是否存在confirm
        if(confirmLogDao.existsById(transId)) {
            log.info("confirm执行过了，{}",transId);
            return ;
        }

        // 回滚余额
        synchronized (this){
            Account account = accountDao.findByAccountNo(accountNo);
            if(account != null) {
                // 能够处理
                BigDecimal result = account.getAccountBalance().add(new BigDecimal(amount));
                account.setAccountBalance(result);
                accountDao.save(account);

            } else {
                throw new RuntimeException("没有这个账户");
            }
        }

        // 增加保存的记录
        confirmLogDao.save(new LocalConfirmLog(transId,new Date()));

    }

    public void cancel(String accountNo, Double amount){
        log.info("cancel方法也是空的...");
    }
}
